import { _decorator, Component } from 'cc';
import { NetworkManager } from './NetworkManager';
import { GameEvents } from '../constants/GameConstants';
import { EventManager } from '../core/EventManager';

const { ccclass, property } = _decorator;

/**
 * 匹配管理器
 * 
 * 功能：
 * 1. 处理玩家匹配
 * 2. 管理匹配队列
 * 3. 处理队伍匹配
 * 4. 提供匹配状态
 * 
 * 特点：
 * 1. 支持多种匹配模式
 * 2. 动态匹配规则
 * 3. 队伍匹配支持
 * 4. 匹配状态反馈
 */
@ccclass('MatchManager')
export class MatchManager extends Component {
    private static _instance: MatchManager | null = null;
    private matchStatus: MatchStatus = MatchStatus.IDLE;
    private matchTimeout: number = 30; // 匹配超时时间（秒）
    private matchTimer: number = 0;
    private matchMode: MatchMode = MatchMode.SOLO;
    private teamId: string = '';

    public static get instance(): MatchManager {
        return this._instance!;
    }

    onLoad() {
        if (MatchManager._instance === null) {
            MatchManager._instance = this;
            this.setupNetworkCallbacks();
        } else {
            this.node.destroy();
        }
    }

    private setupNetworkCallbacks(): void {
        NetworkManager.instance.on('matchFound', this.onMatchFound.bind(this));
        NetworkManager.instance.on('matchCancelled', this.onMatchCancelled.bind(this));
        NetworkManager.instance.on('matchError', this.onMatchError.bind(this));
    }

    public startMatching(mode: MatchMode = MatchMode.SOLO, teamId: string = ''): void {
        if (this.matchStatus !== MatchStatus.IDLE) {
            console.warn('Already in matching process');
            return;
        }

        this.matchMode = mode;
        this.teamId = teamId;
        this.matchStatus = MatchStatus.MATCHING;
        this.matchTimer = 0;

        // 发送匹配请求
        NetworkManager.instance.request('/match/start', {
            mode: this.matchMode,
            teamId: this.teamId
        });

        // 发送匹配开始事件
        EventManager.instance.emit(GameEvents.MATCH_START);
    }

    public cancelMatching(): void {
        if (this.matchStatus !== MatchStatus.MATCHING) return;

        NetworkManager.instance.request('/match/cancel', {
            mode: this.matchMode,
            teamId: this.teamId
        });

        this.resetMatchStatus();
        EventManager.instance.emit(GameEvents.MATCH_CANCEL);
    }

    private onMatchFound(data: MatchResult): void {
        this.matchStatus = MatchStatus.FOUND;
        EventManager.instance.emit(GameEvents.MATCH_FOUND, data);

        // 加入游戏房间
        this.joinGameRoom(data.roomId);
    }

    private onMatchCancelled(): void {
        this.resetMatchStatus();
        EventManager.instance.emit(GameEvents.MATCH_CANCEL);
    }

    private onMatchError(error: string): void {
        this.resetMatchStatus();
        EventManager.instance.emit(GameEvents.MATCH_ERROR, error);
    }

    private async joinGameRoom(roomId: string): Promise<void> {
        try {
            await NetworkManager.instance.request('/room/join', { roomId });
            EventManager.instance.emit(GameEvents.ROOM_JOINED, roomId);
        } catch (error) {
            EventManager.instance.emit(GameEvents.ROOM_JOIN_ERROR, error);
            this.resetMatchStatus();
        }
    }

    update(dt: number) {
        if (this.matchStatus === MatchStatus.MATCHING) {
            this.matchTimer += dt;
            
            // 检查是否超时
            if (this.matchTimer >= this.matchTimeout) {
                this.onMatchTimeout();
            }

            // 发送匹配进度更新事件
            EventManager.instance.emit(
                GameEvents.MATCH_PROGRESS,
                this.matchTimer / this.matchTimeout
            );
        }
    }

    private onMatchTimeout(): void {
        this.resetMatchStatus();
        EventManager.instance.emit(GameEvents.MATCH_TIMEOUT);
    }

    private resetMatchStatus(): void {
        this.matchStatus = MatchStatus.IDLE;
        this.matchTimer = 0;
        this.matchMode = MatchMode.SOLO;
        this.teamId = '';
    }

    onDestroy() {
        NetworkManager.instance.off('matchFound', this.onMatchFound.bind(this));
        NetworkManager.instance.off('matchCancelled', this.onMatchCancelled.bind(this));
        NetworkManager.instance.off('matchError', this.onMatchError.bind(this));
    }
}

enum MatchStatus {
    IDLE,
    MATCHING,
    FOUND
}

enum MatchMode {
    SOLO,
    DUO,
    SQUAD
}

interface MatchResult {
    roomId: string;
    players: {
        id: string;
        name: string;
        team: number;
    }[];
} 